﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace ImageViewerCL
{
	/// <summary>
	/// Interaction logic for PolaroidImage.xaml
	/// </summary>
	public partial class PolaroidImage
    {
        #region FIELDS
        private String caption;
        private String path;
        private bool previewDrag = true;
        #endregion

        #region PROPERTIES
        /// <summary>
        /// Gets/sets the color of the image paper.
        /// </summary>
        new public Brush Background
        {
            get { return (Brush)this.GetValue(BackgroundProperty); }
            set { this.SetValue(BackgroundProperty,value); }
        }

        /// <summary>
        /// Gets/sets the caption text below the image.
        /// </summary>
        public String Caption
        {
            get { return this.caption; }
            set
            {
                this.caption = value;
                this.CaptionText.Text = value;
            }
        }

        /// <summary>
        /// Gets/sets the path of the image displayed.
        /// </summary>
        /// <remarks>You must call the RefreshImage method before the image is displayed.</remarks>
        public String Path
        {
            get { return this.path; }
            set
            {
                this.path = value;
            }
        }

        /// <summary>
        /// Enables or disables live dragging
        /// </summary>
        /// <remarks>Enabled by default.</remarks>
        public bool PreviewDrag
        {
            get { return this.previewDrag; }
            set { this.previewDrag = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public TextAlignment CaptionTextAlignment
        {
            get { return (TextAlignment)this.GetValue(CaptionTextAlignmentProperty); }
            set { this.SetValue(CaptionTextAlignmentProperty, value); }
        }
        #endregion

        #region DEPENDENCY
        /// <summary>
        /// The BackgroundBrush dependencyproperty
        /// </summary>
        /// <seealso cref="ImageViewerCL.PolaroidImage.BackgroundBrush"/>
        public static readonly new DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(PolaroidImage),new FrameworkPropertyMetadata(Brushes.White,FrameworkPropertyMetadataOptions.AffectsRender,new PropertyChangedCallback(OnBackgroundChanged)));
        private static void OnBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PolaroidImage PI = (PolaroidImage)d;
            PI.bg.Fill = (Brush)e.NewValue;
        }

        /// <summary>
        /// The Alignment bs
        /// </summary>
        public static readonly DependencyProperty CaptionTextAlignmentProperty = DependencyProperty.Register("CaptionTextAlignment", typeof(TextAlignment), typeof(PolaroidImage),new FrameworkPropertyMetadata(TextAlignment.Center,FrameworkPropertyMetadataOptions.AffectsRender,new PropertyChangedCallback(OnTextAlignmentChanged)));
        private static void OnTextAlignmentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PolaroidImage PI = (PolaroidImage)d;
            PI.CaptionText.TextAlignment = (TextAlignment)e.NewValue;
        }
        #endregion

        /// <summary>
        /// Create a PolaroidImage object
        /// </summary>
		public PolaroidImage()
		{
			this.InitializeComponent();
		}

        /// <summary>
        /// Create a PolaroidImage object
        /// </summary>
        /// <param name="path">A string containing the absolute path to the image.</param>
        /// <param name="captionText">A string containing the caption text.</param>
        public PolaroidImage(String path, String captionText)
        {
            this.InitializeComponent();
            this.Caption = captionText;
            this.Path = path;
            this.RefreshImage();
        }

        /// <summary>
        /// Create a PolaroidImage object
        /// </summary>
        /// <param name="path">The absolute path of the image.</param>
        public PolaroidImage(String path)
        {
            this.InitializeComponent();
            this.path = path;
            this.RefreshImage();
        }

        /// <summary>
        /// Gets the image at the Path property and displays it.
        /// </summary>
        public void RefreshImage()
        {
            BitmapImage bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.UriSource = new Uri(this.path, UriKind.Absolute);
            bmp.EndInit();
            this.content.Source = bmp;
        }

        /// <summary>
        /// Makes the caption text field editable
        /// </summary>
        private void BeginEditCaption()
        {
            this.CaptionText.IsReadOnly = false;
            this.CaptionText.Focus();
            this.CaptionText.SelectAll();
        }

        /// <summary>
        /// Makes the caption text field read only again
        /// </summary>
        private void EndEditCaption()
        {
            this.CaptionText.IsReadOnly = true;
            this.Focus();
        }

        /// <summary>
        /// Enables caption editing
        /// </summary>
        private void CaptionText_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            BeginEditCaption();
        }

        /// <summary>
        /// Disables caption editing
        /// </summary>
        private void CaptionText_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.Key == Key.Enter) || (e.Key == Key.Return))
            {
                EndEditCaption();
            }
        }

        /// <summary>
        /// Disables caption editing
        /// </summary>
        private void CaptionText_LostFocus(object sender, RoutedEventArgs e)
        {
            EndEditCaption();
        }

        /// <summary>
        /// Handles drag move if live dragging is enabled
        /// </summary>
        private void DragThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (previewDrag)
            {
                double top = this.Margin.Top;
                double left = this.Margin.Left;
                double bottom = this.Margin.Bottom;
                double right = this.Margin.Right;

                // adjust the vertical position
                top -= -e.VerticalChange;

                // adjust the horizontal position
                left -= -e.HorizontalChange;

                this.Margin = new Thickness(left, top, right, bottom);
            }
        }

        /// <summary>
        /// Handles drag move if live dragging is disabled
        /// </summary>
        private void DragThumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            if (!previewDrag)
            {
                double top = this.Margin.Top;
                double left = this.Margin.Left;
                double bottom = this.Margin.Bottom;
                double right = this.Margin.Right;

                // adjust the vertical position
                top -= -e.VerticalChange;

                // adjust the horizontal position
                left -= -e.HorizontalChange;

                this.Margin = new Thickness(left, top, right, bottom);
            }
        }
	}
}